/*
 * Copyright (c) Zhongkehonglue Technologies Co., Ltd. 2025. All rights reserved.
 * Description: Implementation of functions related to the DMC DEV module.
 * Author: wangchunyang
 * Create: 2025-05-23
 */

#include "dmcRc.h"
#include "dmcLog.h"
#include "dmcConstant.h"
#include "dmcApiTypes.h"
#include "dmcSendAction.h"

#ifdef LOG_TAG
#undef LOG_TAG
#endif
namespace DlnaDmc {

dmc_int32 DmcSetVolume(dmc_uint32 deviceId, dmc_uint32 instanceId,
    DmcChannelType enChannel, dmc_uint32 volume)
{
    LOGI("set volume deviceId = %{public}d, instanceId = %{public}d, \
        enChannel = %{public}d, volume = %{public}d",
         deviceId, instanceId, enChannel, volume);
    DmcActionInfo actionInfo;
    actionInfo.actionName = "SetVolume";
    actionInfo.serviceType = renderingControlServiceStr;
    actionInfo.paraInfo.insert({"InstanceID", std::to_string(instanceId)});
    actionInfo.paraInfo.insert({"Channel", DmcGetChannelStr(enChannel)});
    actionInfo.paraInfo.insert({"DesiredVolume", std::to_string(volume)});

    IXML_Document *resultDoc = nullptr;
    dmc_int32 retVal = DmcSendAction(deviceId, actionInfo, &resultDoc);
    if (retVal != DMC_SUCCESS) {
        LOGE("DmcSendAction failed, error code = %d", retVal);
        return DMC_FAILURE;
    }
    ixmlDocument_free(resultDoc);
    return DMC_SUCCESS;
}

dmc_int32 DmcGetVolume(dmc_uint32 deviceId, dmc_uint32 instanceId,
    DmcChannelType enChannel, dmc_uint32 &currentVolume)
{
    LOGI("get volume deviceId = %{public}d, instanceId = %{public}d, \
        enChannel = %{public}d", deviceId, instanceId, enChannel);
    DmcActionInfo actionInfo;
    actionInfo.actionName = "GetVolume";
    actionInfo.serviceType = renderingControlServiceStr;
    actionInfo.paraInfo.insert({"InstanceID", std::to_string(instanceId)});
    actionInfo.paraInfo.insert({"Channel", DmcGetChannelStr(enChannel)});

    IXML_Document *resultDoc = nullptr;
    dmc_int32 retVal = DmcSendAction(deviceId, actionInfo, &resultDoc);
    if (retVal != DMC_SUCCESS) {
        LOGE("DmcSendAction failed, error code = %d", retVal);
        return DMC_FAILURE;
    }
    const char* volume = DmcGetXmlElementValueFromDoc(resultDoc, "CurrentVolume");
    if (volume == nullptr) {
        ixmlDocument_free(resultDoc);
        LOGE("get current volume nullptr");
        return DMC_FAILURE;
    }
    currentVolume = static_cast<dmc_uint32>(std::stoi(volume));
    LOGI("currentVolume = %{public}d", currentVolume);
    ixmlDocument_free(resultDoc);
    return DMC_SUCCESS;
}

dmc_int32 DmcSetMute(dmc_uint32 deviceId, dmc_uint32 instanceId,
    DmcChannelType enChannel, bool mute)
{
    LOGI("set mute deviceId = %{public}d, instanceId = %{public}d, enChannel = %{public}d, \
         mute = %{public}d", deviceId, instanceId, enChannel, mute);
    DmcActionInfo actionInfo;
    actionInfo.actionName = "SetMute";
    actionInfo.serviceType = renderingControlServiceStr;
    actionInfo.paraInfo.insert({"InstanceID", std::to_string(instanceId)});
    actionInfo.paraInfo.insert({"Channel", DmcGetChannelStr(enChannel)});
    std::string desiredMuteStr = mute ? "true":"false";
    actionInfo.paraInfo.insert({"DesiredMute", desiredMuteStr});

    IXML_Document *resultDoc = nullptr;
    dmc_int32 retVal = DmcSendAction(deviceId, actionInfo, &resultDoc);
    if (retVal != DMC_SUCCESS) {
        LOGE("DmcSendAction failed, error code = %d", retVal);
        return DMC_FAILURE;
    }
    ixmlDocument_free(resultDoc);
    return DMC_SUCCESS;
}

std::string DmcGetChannelStr(DmcChannelType channel)
{
    std::string str;
    switch (channel) {
        case DMC_CHANNEL_TYPE_B:
            str = "B";
            break;
        case DMC_CHANNEL_TYPE_CF:
            str = "CF";
            break;
        case DMC_CHANNEL_TYPE_LF:
            str = "LF";
            break;
        case DMC_CHANNEL_TYPE_LFC:
            str = "LFC";
            break;
        case DMC_CHANNEL_TYPE_LFE:
            str = "LFE";
            break;
        case DMC_CHANNEL_TYPE_LS:
            str = "LS";
            break;
        case DMC_CHANNEL_TYPE_MASTER:
            str = "Master";
            break;
            case DMC_CHANNEL_TYPE_RF:
            str = "RF";
            break;
        case DMC_CHANNEL_TYPE_RFC:
            str = "RFC";
            break;
        case DMC_CHANNEL_TYPE_RS:
            str = "RS";
            break;
        case DMC_CHANNEL_TYPE_SD:
            str = "SD";
            break;
        case DMC_CHANNEL_TYPE_SL:
            str = "SL";
            break;
        case DMC_CHANNEL_TYPE_SR:
            str = "SR";
            break;
        case DMC_CHANNEL_TYPE_T:
            str = "T";
            break;
        default:
            LOGE("Invalid channel value = %{public}d", channel);
    }
    return str;
}
}





